package com.gopay.bis.service.bank.impl.expay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.expay.UmPayMtPayManager;
import com.gopay.bis.service.bank.sms.SmsSupportController;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.QueryNeedCertConstants;
import com.gopay.common.constants.bank.SmsConstants;
import com.gopay.common.constants.bank.UmPayConstants;
import com.gopay.common.constants.bank.YeePayConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.umpay.mtpay.UmPayMtPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.MoneyUtil;
import com.gopay.remote.bank.ExPayInteractRemoteService;

public class UmPayMtPayServiceImpl implements ExPayInteractRemoteService {
	@Resource(name = "umPayMtPayManager")
	private UmPayMtPayManager umPayMtPayManager;
	// 短信验证码处理类
	public SmsSupportController smsController;
	
	/**
	 * 是否需要输入cvv2
	 */
    public Result queryCvn(ExPayBaseMessage baseMsg) {
        Result result = new Result();
        result.setSuccess(true);
        result.setModel("flag", true);
        result.setModel("isQueryCVN", YeePayConstants.YEEPAY_EXPAY_ISQUERYCVN);
        return result;
    }
	
	/**
	 * 认证请求
	 */
	public Result certification(ExPayBaseMessage baseMsg) {
		Result result = new Result();
		result.setSuccess(true);
		result.setModel("flag", true);
		return result;
	}
	
	/**
	 * 发送短信验证码请求
	 */
	public Result sendSms(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		UmPayMtPayMessage message = new UmPayMtPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
		    Map<String, String> smsRes = smsController.sendSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6102.equals(smsRes.get("resCode"))) {
                // 短信发送成功
                result.setModel("flag", true);
            } else {
                // 短信发送失败
                result.setModel("flag", false);
            }
            result.setModel("sendCount", smsRes.get("sendCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6077);
		}
		return result;
	}
	
	/**
	 * 验证短信请求
	 */
	public Result checkSms(ExPayBaseMessage baseMsg) {
		Result result = new Result(false);
		UmPayMtPayMessage message = new UmPayMtPayMessage();
		BeanUtils.copyProperties(baseMsg, message);
		try {
		    Map<String, String> smsRes = smsController.checkSMS(message);
            if (ProcCodeConstants.PROC_CODE_100E6091.equals(smsRes.get("resCode"))) {
                // 验证通过
                result.setModel("flag", true);               
            } else {
                // 验证失败
                result.setModel("flag", false);
                if(!ProcCodeConstants.PROC_CODE_100E6099.equals(smsRes.get("resCode"))){
                    Map<String, String> freezeRes = smsController.freezeCard(message);
                    if(freezeRes != null)
                        smsRes = freezeRes;
                }
            }
            result.setModel("failCount", smsRes.get("failCount"));
            result.setModel("retMsg", smsRes.get("retMsg"));
            result.setModel("resCode", smsRes.get("resCode"));
            result.setResultCode(smsRes.get("resCode"));
            result.setSuccess(true);
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6078);
		}
		return result;
	}
	
	/**
	 * 支付请求
	 */
	public Result payment(ExPayBaseMessage base) {
		Result result = new Result(false);
		base.setBankOrderId("UM" + TransUtil.processOrderIdTo14Digit(base.getOrderId()));
		UmPayMtPayMessage message = new UmPayMtPayMessage();
		BeanUtils.copyProperties(base, message);
		try {
			message = (UmPayMtPayMessage) umPayMtPayManager.sign(message);
			result.setDefaultModel(message);
            if (UmPayConstants.RES_CODE_SUCCESS.equals(message.getRetCode())
                    && UmPayConstants.TRADE_SUCCESS.equals(message.getTradeState())){
				result.setModel("flag", true);
			}else{
				result.setModel("flag", false);
				result.setModel("retMsg", message.getRetMsg());
			}
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6057);
		}
		return result;
	}
	/**
	 * 银行返回类请求
	 * 
	 * @param BaseMessage
	 * @return Result
	 */
	public Result verify(ExPayBaseMessage base) {
		Result result = new Result(false);
		try {
			UmPayMtPayMessage message = new UmPayMtPayMessage();
			BeanUtils.copyProperties(base, message);
			UmPayMtPayMessage umPayMessage = (UmPayMtPayMessage) umPayMtPayManager.verify(message);
			
			result.setModel("res", umPayMessage);
			
			Map<String, String> param = new HashMap<String, String>();
			if (UmPayConstants.TRADE_SUCCESS.equals(umPayMessage.getTradeState())) {
				param.put("orderId", message.getOrderId());
				param.put("amt", formatAmt(message.getAmount().toString()));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("signData", message.getSignMessage());
				param.put("isFront", String.valueOf(base.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setDefaultModel(true);
				result.setOrderStatus(true);
			} else {
				// 通知后台地址该订单失败
				param.put("orderId", message.getOrderId());
				param.put("amt", formatAmt(message.getAmount().toString()));
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				param.put("retMsg", "验签失败");
				param.put("signData", message.getSignMessage());
				param.put("isFront", String.valueOf(base.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setSuccess(true);
				result.setOrderStatus(false);
			}
		
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;
	}
	
	@Override
	public Result queryOrder(ExPayBaseMessage base) {
		Result result = new Result(false);
		UmPayMtPayMessage message = new UmPayMtPayMessage();
		BeanUtils.copyProperties(base, message);
		try {
			message = (UmPayMtPayMessage) umPayMtPayManager.query(message);
			result.setDefaultModel(message);
			result.setSuccess(true);
			if(BisPayCheckUtils.checkExternalOrderID(base.getOrderId())){
				Map<String, String> param = new HashMap<String, String>();
				String amount = base.getAmount().toString();
				amount = MoneyUtil.formatAmt(amount);
				param.put("orderId", base.getOrderId());
				param.put("amount", amount);
				if (message == null) {
					// 查询结果为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}

//				String retCode = message.getRetCode(); // 返回码
//				String retMsg = message.getRetMsg(); // 返回信息
//				String errorCode = message.getErrorCode(); // 交易错误码
				String tradeStatus = message.getTradeState(); // 订单状态
				//成功处理
				if (UmPayConstants.TRADE_SUCCESS.equals(tradeStatus)) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
					param.put("returnMessage", "交易成功");
				}
				//失败处理
				else if (UmPayConstants.TRADE_FAIL.equals(tradeStatus)) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
					param.put("returnMessage", "交易失败");
				}
				//不处理
				else if (UmPayConstants.TRADE_CANCEL.equals(tradeStatus)) {
					// 交易撤销
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行返回交易已撤销");
				} else if (UmPayConstants.TRADE_CLOSED.equals(tradeStatus)) {
					// 交易关闭
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行返回交易已关闭");
				} else if (UmPayConstants.WAIT_BUYER_PAY.equals(tradeStatus)) {
					// 交易等待付款
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行返回交易等待付款");
				} else {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行返回交易状态不明");
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6058);
		}
		return result;
	}
	
	protected String formatAmt(String amtStr) {

		// 增加校验功能，防止误操作
		if (amtStr.indexOf(".") > -1) {
			return amtStr;
		}

		BigDecimal amt = null;
		try {
			amt = new BigDecimal(amtStr);
		} catch (Exception e) {
			amt = new BigDecimal("0");
		}
		amt = amt.movePointLeft(2);
		return amt.toString();
	}
	
	public SmsSupportController getSmsController() {
		return smsController;
	}
	public void setSmsController(SmsSupportController smsController) {
		this.smsController = smsController;
	}
	@Override
	public Result sign(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result treatyQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result cancel(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result refund(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}

    @Override
    public Result queryNeedCert(ExPayBaseMessage baseMsg) {
        Result result = new Result();
        result.setSuccess(true);
        result.setModel("NeedMark", QueryNeedCertConstants.QUERY_RESULT_NONEED);
        return result;
    }
/*	@Override
	public Result refundQuery(ExPayBaseMessage baseMsg) {
		// TODO Auto-generated method stub
		return null;
	}*/

    @Override
    public Result refundBack(ExPayBaseMessage baseMsg) {
        // TODO Auto-generated method stub
        return null;
    }
}
